﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Controls;

using PlanningGIS.Util.Convertor;
using PlanningGIS.ArcGIS;
using PlanningGIS.Util.Log;
using PlanningGIS.Engine.Controls;

namespace PlanningGIS.DataCheck.model
{
    /// <summary>
    /// 水系线面高程不一致检查（对于水库、山塘、湖泊、池塘检查其高程值和对应的常水位岸线是否一致）
    /// </summary>
    public class HydPyLnElevationCheck : Check
    {
        public int Check(string errType, IFeatureLayer pFeatLyrPy, IFeatureLayer pFeatLyrLn, IGeometry pGeometry, 
            string whereClause,string fcodename, string elevationname)
        {
            IFeatureClass pFeatClsPy = pFeatLyrPy.FeatureClass;
            IFeatureClass pFeatClsLn = pFeatLyrLn.FeatureClass;

            if (pFeatClsLn.ShapeType != esriGeometryType.esriGeometryPolyline)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrLn.Name + "]图层不是线状图层，检查失败！");
                return -1;
            }

            if (pFeatClsPy.ShapeType != esriGeometryType.esriGeometryPolygon)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrPy.Name + "]图层不是面状图层，检查失败！");
                return -1;
            }

            int idxfcodepy = pFeatClsPy.FindField(fcodename);
            if (idxfcodepy == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrPy.Name + "]图层中未找到分类代码[" + fcodeName + "]字段，检查失败！");
                return -1;
            }

            int idxfcodeln = pFeatClsLn.FindField(fcodename);
            if (idxfcodeln == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrLn.Name + "]图层中未找到分类代码[" + fcodeName + "]字段，检查失败！");
                return -1;
            }

            int idxelevationln = pFeatClsLn.FindField(elevationname);
            if (idxelevationln == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrLn.Name + "]图层中未找到高程[" + elevationname + "]字段，检查失败！");
                return -1;
            }

            int idxelevationpy = pFeatClsPy.FindField(elevationname);
            if (idxelevationpy == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrPy.Name + "]图层中未找到高程[" + elevationname + "]字段，检查失败！");
                return -1;
            }

            ISpatialFilter pSpatialFileter = new SpatialFilterClass();
            if (pGeometry != null) pSpatialFileter.Geometry = pGeometry;

            string sql = fcodename + " in('240101500','240102500','240104500','230100500','230200500')";
            pSpatialFileter.WhereClause = whereClause == "" ? sql : whereClause + " and " + sql;

            pSpatialFileter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            pSpatialFileter.GeometryField = pFeatClsPy.ShapeFieldName;

            showFakePro(true);
            LogHelper.WriteLog("正在计算需要检查的要素数目...");

            int max = FeatureClassHelper.GetFeatureCountFromLayer(pFeatLyrPy, pSpatialFileter);
            

            LogHelper.WriteLog("计算完毕。共有" + max + "个要素参与检查。");
            showFakePro(false);

            if (max == 0)
            {
                LogHelper.WriteLog("没有满足检查要求的要素存在。");
                return -1;
            }

            setProcessBarMax(max);

            IFeatureCursor pFeatCur;
            pFeatCur = pFeatLyrPy.Search(pSpatialFileter, false);

            IFeature pFeaturePy;

            int count = 0;
            int errCount = 0;

            while ((pFeaturePy = pFeatCur.NextFeature()) != null)
            {
                if (IsStop()) break;

                setProcessBarCurrent(count);
                count++;

                double elevationvaluepy;
                if (StringHelper.CanConvert2Double(pFeaturePy.get_Value(idxelevationpy)))
                {
                    elevationvaluepy = Double.Parse(StringHelper.ConvertWRTNull(pFeaturePy.get_Value(idxelevationpy)));
                }
                else
                {
                    RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "高程字段不能转化为数值");
                    errCount++;
                    continue;
                }

                IFeatureCursor pFeatCurLn = CursorHelper.GetCursor(pFeatClsLn, pFeaturePy.ShapeCopy, fcodename + " = '260911350'");
                IFeature pFeatureLn = pFeatCurLn.NextFeature();

                //如果通过通过静水面找不到常水位岸线，则认为是错误的
                if (pFeatCurLn == null)
                {
                    RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "未找到常水位线");
                    errCount++;
                }

                while (pFeatureLn != null)
                {
                    double elevationvalueln;

                    if (StringHelper.CanConvert2Double(pFeatureLn.get_Value(idxelevationln)))
                    {
                        elevationvalueln = Double.Parse(StringHelper.ConvertWRTNull(pFeatureLn.get_Value(idxelevationln)));

                        if (elevationvaluepy != elevationvalueln)
                        {
                            ITopologicalOperator2 pTop = pFeaturePy.ShapeCopy as ITopologicalOperator2;
                            //pTop = pTop.Boundary as ITopologicalOperator2;
                            IPolyline pPolyline = pTop.Intersect(pFeatureLn.ShapeCopy, esriGeometryDimension.esriGeometry1Dimension) as IPolyline;
                            if (pPolyline == null || pPolyline.IsEmpty) continue;

                            RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, pFeatureLn, pPolyline, "");
                            errCount++;
                        }
                    }
                    else
                    {
                        RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, pFeatureLn, pFeatureLn.ShapeCopy, "高程字段不能转化为数值");
                        errCount++;
                    }

                    pFeatureLn = pFeatCurLn.NextFeature();
                }

                DataCheckUtility.ReleaseComObject(pFeatCurLn);
            }

            finishPro.Invoke();

            DataCheckUtility.ReleaseComObject(pFeaturePy);
            DataCheckUtility.ReleaseComObject(pFeatCur);

            LogHelper.WriteLog("水系线面高程不一致检查结束。共发现" + errCount + "处错误！\n");

            return errCount;
        }

    }
}
